<!--
 * @FileDescription 终端
 * @Author lz
 * @Date 20230330 10:57:59
 * @LastEditors lz
 * @LastEditTime 20230330 10:57:59
-->
<template>
    <div class="TerBox">
        <div class="headerBox">
            <div class="labBox">
                File
            </div>
            <div class="labBox">
                Edit
            </div>
            <div class="labBox">
                View
            </div>
            <div class="labBox">
                Search
            </div>
            <div class="labBox">
                Termlnal
            </div>
            <div class="labBox">
                Help
            </div>
            <CloseOutlined class="CloseOutlined" @click="ret()" />
        </div>
        <div class="DataListBox" id="scrolldIV">
            <div class="DataList" v-for="(item, index) in state.TerminalDataList" :key="index">
                <div v-if="state.StepSequence == 2">
                    <span class="names">{{ item.names }} </span><a-input-password v-model:value="item.inpVal" ref="refDiv"
                        @pressEnter="pressEnter(item.inpVal, index)" class="dataInput" v-if="item.types == 0" />
                    <span v-else class="names_2">&nbsp;&nbsp;{{ item.inpVal }}</span>
                </div>
                <div v-else>
                    <span class="names">{{ item.names }} </span><a-input v-model:value="item.inpVal" ref="refDiv"
                        @pressEnter="pressEnter(item.inpVal, index)" class="dataInput" v-if="item.types == 0" />
                    <span v-if="item.types != 0 && item.inpVal != 'apollo'" class="names_2">&nbsp;&nbsp;{{ item.inpVal
                    }}</span>
                    <span v-if="item.types != 0 && item.inpVal == 'apollo'"
                        class="names_2 ciphertext">&nbsp;&nbsp;••••••</span>
                </div>
            </div>
        </div>

    </div>
</template>

<script setup lang="ts">
import { CloseOutlined } from '@ant-design/icons-vue';
import { ClientMessage } from '@runtime/generate/message/ClientMessage';
import WebSocketComponent from '@runtime/module/WebSocket/WebSocketComponent';
import { message } from 'ant-design-vue';
import { reactive, ref, toRefs, onBeforeMount, onMounted, nextTick, watch } from 'vue'
import HomeContent from '../HomeContent';
let KeyVal = ref('');

document.onkeydown = function (e) {
    if (e.key == 'Control') {
        KeyVal.value = e.key
    }
    if (e.key == 'c' || e.key == 'C') {
        if (KeyVal.value == 'Control') {
            WebSocketComponent.Default.PostMessageAsync(new ClientMessage.NeolithUnmannedKeyBoardRequest('ctrl,c'))
        }
    } if (e.key == 'ArrowUp') {
        if (HomeContent.Default.TerminalRecords.value.length > 0) {
            if (HomeContent.Default.TerminalNnum.value > -1) {
                state.TerminalDataList[state.TerminalDataList.length - 1].inpVal = HomeContent.Default.TerminalRecords.value[HomeContent.Default.TerminalNnum.value]
                HomeContent.Default.TerminalNnum.value--
            }
        }
    }
    if (e.key == 'ArrowDown') {
        if (HomeContent.Default.TerminalRecords.value.length > 0) {
            if (HomeContent.Default.TerminalNnum.value < HomeContent.Default.TerminalRecords.value.length) {
                state.TerminalDataList[state.TerminalDataList.length - 1].inpVal = HomeContent.Default.TerminalRecords.value[HomeContent.Default.TerminalNnum.value]
                HomeContent.Default.TerminalNnum.value++
            }
        }
    }
}

document.onkeyup = function (e) {
    KeyVal.value = ''
}

const refDiv = ref()
// 定义函数
function page_scroll() {
    var i = 1
    var element = document.getElementById("scrolldIV")
    // element!.scrollTop = 0;  // 不管他在哪里，都让他先回到最上面
    // console.log(element!.scrollTop);
    // console.log(element!.clientHeight);
    // console.log(element!.scrollHeight);

    // 设置定时器，时间即为滚动速度
    function main() {
        if (element!.scrollTop + element!.clientHeight == element!.scrollHeight) {
            clearInterval(interval)
            console.log('已经到底部了')
        } else {
            element!.scrollTop += 300;
            console.log(i);
            i += 1;
        }
    }
    // 定义ID
    const interval = setInterval(main, 200)
}

const state = reactive({
    TerminalDataList: [
        { names: 'apollo@baibu:~$', inpVal: '', types: 0 },
    ],
    // 记录步骤
    StepSequence: 0,
    //记录当前输入框
    inpSeq: 0,
});
function ret() {
    HomeContent.Default.UBANTUVal.value = 0
}
// 终端反馈
async function pressEnter(val: string, index: number) {
    state.inpSeq = index
    HomeContent.Default.TerminalRecords.value.push(val)
    HomeContent.Default.TerminalNnum.value = HomeContent.Default.TerminalRecords.value.length - 1

    //发送终端内容
    await WebSocketComponent.Default.PostMessageAsync(new ClientMessage.NeolithTrackContentRequest(val));


    state.TerminalDataList[index].types = 1
    if (state.StepSequence == 0) {
        if (val == 'cd ~/socketcan') {

            state.StepSequence = 1
            state.TerminalDataList.push({ names: 'apollo@baibu:~/socketcan$', inpVal: '', types: 0 })
        } else {
            message.error('无当前指令');
            state.TerminalDataList.push({ names: 'apollo@baibu:~$', inpVal: '', types: 0 })
        }
    } else if (state.StepSequence == 1) {
        if (val == 'bash start.sh') {
            // await WebSocketComponent.Default.PostMessageAsync(new ClientMessage.NeolithTrackContentRequest('bash start.sh'))

            state.StepSequence = 2
            state.TerminalDataList.push({ names: '[sudo] password for apollo:', inpVal: '', types: 0 })
        } else {
            message.error('无当前指令');
            state.TerminalDataList.push({ names: 'apollo@baibu:~/socketcan$', inpVal: '', types: 0 })
        }
    }
    else if (state.StepSequence == 2) {
        if (val == 'apollo') {
            // await WebSocketComponent.Default.PostMessageAsync(new ClientMessage.NeolithTrackContentRequest('bash start.sh'))

            state.StepSequence = 3
            state.TerminalDataList.push({ names: 'rmmod:ERROR:Module emuc2socketcan', inpVal: '', types: 1 })
            state.TerminalDataList.push({ names: 'apollo@baibu:~/socketcan$', inpVal: '', types: 0 })
        } else {
            message.error('无当前指令');
            state.TerminalDataList.push({ names: '[sudo] password for apollo:', inpVal: '', types: 0 })
        }
    }
    else if (state.StepSequence == 3) {
        if (val == 'ifconfig') {
            // await WebSocketComponent.Default.PostMessageAsync(new ClientMessage.NeolithTrackContentRequest('apollo'))
            //CAN启动成功
            await WebSocketComponent.Default.PostMessageAsync(new ClientMessage.NeolithTrackCANStartRequest(true))

            state.StepSequence = 4
            state.TerminalDataList.push({
                names: 'apollo@baibu:', inpVal: `
rmmod: ERROR: Module emuc2socketcan is not currently loaded
apollo@baidu:~/socketcan$ ifconfig
can0: flags=193<UP,RUNNING,NOARP>  mtu 16
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 1000  (UNSPEC)
        RX packets 4069  bytes 32552 (32.5 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 1  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

can1: flags=193<UP,RUNNING,NOARP>  mtu 16
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 1000  (UNSPEC)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device base 0x101  

docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:88:33:72:26  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

enp0s31f6: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.10.6  netmask 255.255.0.0  broadcast 192.168.255.255
        inet6 fe80::7ad0:4ff:fe2f:1807  prefixlen 64  scopeid 0x20<link>
        ether 78:d0:04:2f:18:07  txqueuelen 1000  (Ethernet)
        RX packets 515336  bytes 665848558 (665.8 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 1418  bytes 275371 (275.3 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device interrupt 16  memory 0xa4400000-a4420000  

enp8s0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        ether 78:d0:04:2f:18:08  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device memory 0xa4200000-a427ffff  

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 103110  bytes 161273056 (161.2 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 103110  bytes 161273056 (161.2 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0`, types: 1
            })
            state.TerminalDataList.push({ names: 'apollo@baibu:~$', inpVal: '', types: 0 })

        } else {
            message.error('无当前指令');
            state.TerminalDataList.push({ names: '[sudo] password for apollo:', inpVal: '', types: 0 })
        }
    }
    else if (state.StepSequence == 4) {
        if (val == 'cd ~/apollo') {
            // await WebSocketComponent.Default.PostMessageAsync(new ClientMessage.NeolithTrackContentRequest('cd ~/apollo'))

            state.StepSequence = 5
            state.TerminalDataList.push({ names: 'apollo@baibu:~/apollo$', inpVal: '', types: 0 })
        } else {
            message.error('无当前指令');
            state.TerminalDataList.push({ names: 'apollo@baibu:~$', inpVal: '', types: 0 })
        }
    } else if (state.StepSequence == 5) {
        if (val == 'bash apollo.sh') {
            // await WebSocketComponent.Default.PostMessageAsync(new ClientMessage.NeolithTrackContentRequest('bash apollo.sh'))

            state.StepSequence = 6
            state.TerminalDataList.push({
                names: 'apollo@baibu:', inpVal: `Welcome to
    ___                ____    
   /   |  ____  ____  / / /___ 
  / /| | / __ \/ __ \/ / / __ \
 / ___ |/ /_/ / /_/ / / / /_/ /
/_/  |_/ .___/\____/_/_/\____/ 
      /_/ 
Found existing container. If you need a fresh one, run 'docker rm -f apollo_runtime_standalone_apollo' out of the container first.
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.`, types: 1
            })
            state.TerminalDataList.push({ names: '[apollo@in-runtime-docker:/apollo]:$', inpVal: '', types: 0 })

        } else {
            message.error('无当前指令');
            state.TerminalDataList.push({ names: 'apollo@baibu:~/apollo$', inpVal: '', types: 0 })
        }
    }
    else if (state.StepSequence == 6) {
        if (val == 'bootstrap.sh') {
            // await WebSocketComponent.Default.PostMessageAsync(new ClientMessage.NeolithTrackContentRequest('bootstrap.sh'))

            state.StepSequence = 7
            state.TerminalDataList.push({
                names: 'apollo@baibu:', inpVal: `nohup: appending output to 'nohup.out'
[ OK ] Launched module monitor.
nohup: appending output to 'nohup.out'
[ OK ] Launched module dreamview.
Dreamview is running at http://localhost:8888`, types: 1
            })
            state.TerminalDataList.push({ names: 'apollo@baibu:', inpVal: '', types: 0 })
            HomeContent.Default.UBANTUType.value = 1

            setTimeout(() => {
                HomeContent.Default.UBANTUVal.value = 1
            }, 2000);
        } else {
            message.error('无当前指令');
            state.TerminalDataList.push({ names: '[apollo@in-runtime-docker:/apollo]:$', inpVal: '', types: 0 })
        }
    } else if (state.StepSequence == 7) {
        if (val == 'cd data/bag') {

            state.StepSequence = 8
            state.TerminalDataList.push({ names: '[apollo@in-runtime-docker:/apollo/data/bag]:$', inpVal: '', types: 0 })
        } else {
            message.error('无当前指令');
            state.TerminalDataList.push({ names: '[apollo@in-runtime-docker:/apollo]:$', inpVal: '', types: 0 })
        }
    } else if (state.StepSequence == 8) {
        if (val == 'rm -rf map_tmp') {

            state.StepSequence = 9
            state.TerminalDataList.push({ names: '[apollo@in-runtime-docker:/apollo/data/bag]:$', inpVal: '', types: 0 })
        } else {
            message.error('无当前指令');
            state.TerminalDataList.push({ names: '[apollo@in-runtime-docker:/apollo/data/bag]:$', inpVal: '', types: 0 })
        }
    } else if (state.StepSequence == 9) {
        if (val == 'mkdir map_tmp') {

            state.StepSequence = 10
            state.TerminalDataList.push({ names: '[apollo@in-runtime-docker:/apollo/data/bag]:$', inpVal: '', types: 0 })
        } else {
            message.error('无当前指令');
            state.TerminalDataList.push({ names: '[apollo@in-runtime-docker:/apollo/data/bag]:$', inpVal: '', types: 0 })
        }
    } else if (state.StepSequence == 10) {
        if (val == 'cd map_tmp') {

            state.StepSequence = 11
            state.TerminalDataList.push({ names: '[apollo@in-runtime-docker:/apollo/data/bag/map_tmp]:$', inpVal: '', types: 0 })
        } else {
            message.error('无当前指令');
            state.TerminalDataList.push({ names: '[apollo@in-runtime-docker:/apollo/data/bag/map_tmp]:$', inpVal: '', types: 0 })
        }
    } else if (state.StepSequence == 11) {
        if (val == 'cyber_recorder record -c /apollo/localization/pose') {

            state.StepSequence = 12
            state.TerminalDataList.push({ names: '[apollo@in-runtime-docker:]', inpVal: '[RUNNING] Record Time :168421901 Progress: 1 channels , 1 messages', types: 1 })
            state.TerminalDataList.push({ names: '[apollo@in-runtime-docker:/apollo/data/bag/map_tmp]:$', inpVal: '', types: 0 })
        } else {
            message.error('无当前指令');
            state.TerminalDataList.push({ names: '[apollo@in-runtime-docker:/apollo/data/bag/map_tmp]:$', inpVal: '', types: 0 })
        }
    } else if (state.StepSequence == 12) {
        if (val == 'cd /apollo') {

            state.StepSequence = 13
            state.TerminalDataList.push({ names: '[apollo@in-runtime-docker:/apollo]:$', inpVal: '', types: 0 })

        } else {
            message.error('无当前指令');
            state.TerminalDataList.push({ names: '[apollo@in-runtime-docker:/apollo/data/bag/map_tmp]:$', inpVal: '', types: 0 })
        }
    } else if (state.StepSequence == 13) {
        if (val == 'mkdir map_tmp') {

            state.StepSequence = 14
            state.TerminalDataList.push({
                names: '[apollo@in-runtime-docker]:$', inpVal: `mkdir:cannot create directory map_tmp:File exists`, types: 1
            })

            state.TerminalDataList.push({ names: '[apollo@in-runtime-docker:/apollo]:$', inpVal: '', types: 0 })
        } else {
            message.error('无当前指令');
            state.TerminalDataList.push({ names: '[apollo@in-runtime-docker:/apollo]:$', inpVal: '', types: 0 })
        }
    } else if (state.StepSequence == 14) {
        if (val == 'python modules/tools/map_gen/extract_path.py ./map_tmp/map_name.csv ./data/bag/map_tmp/*') {

            state.StepSequence = 15
            state.TerminalDataList.push({
                names: '[apollo@in-runtime-docker]:$', inpVal: `WARNING: Logging berore InitGoogLelogging() is written to STODERR 
I0516 14:42:34.004084 10449 py_record.cc:574] []init _cyber_record_wrapper
File written to: ./map_tmp/map_name.csv`, types: 1
            })

            state.TerminalDataList.push({ names: '[apollo@in-runtime-docker:/apollo]:$', inpVal: '', types: 0 })
        } else {
            message.error('无当前指令');
            state.TerminalDataList.push({ names: '[apollo@in-runtime-docker:/apollo]:$', inpVal: '', types: 0 })
        }
    } else if (state.StepSequence == 15) {
        if (val == 'cd /apollo') {

            state.StepSequence = 16
            state.TerminalDataList.push({ names: '[apollo@in-runtime-docker:/apollo]:$', inpVal: '', types: 0 })
        } else {
            message.error('无当前指令');
            state.TerminalDataList.push({ names: '[apollo@in-runtime-docker:/apollo]:$', inpVal: '', types: 0 })
        }
    } else if (state.StepSequence == 16) {
        if (val == 'bash scripts/create_map_from_xy.sh xy ./map_tmp/map_name.csv') {

            state.StepSequence = 0
            state.TerminalDataList.push({
                names: '[apollo@in-runtime-docker]:$', inpVal: `argument --xy is required
scripts/create_map_from_xy.sh --xy [--map_name MAP_NAME][--left_lane_num 0][--righ_lane_num 0]
scripts/create_map_from_xy.sh --xy set the lnput xy file,file that contains x,y
scripts/create_map_from_xy.sh --map_name set the name of the map, default is the base name of the csv file`, types: 1
            })

            state.TerminalDataList.push({ names: '[apollo@in-runtime-docker:/apollo]:$', inpVal: '', types: 0 })
        } else {
            message.error('无当前指令');
            state.TerminalDataList.push({ names: '[apollo@in-runtime-docker:/apollo]:$', inpVal: '', types: 0 })
        }
    }

    page_scroll();
    // (document.querySelector("#scrolldIV > div:last-of-type > div > input") as HTMLInputElement)?.focus()
    nextTick(() => {
        refDiv.value[0].focus()
    })
}
onMounted(() => {
    nextTick(() => {
        refDiv.value[0].focus()
    })
})
</script>

<style scoped>
.TerBox {
    width: 1854px;
    height: 1050px;
    background-color: #000;
    position: absolute;
    bottom: 0;
    right: 0;
    padding-top: 40px;
}

.DataListBox {
    height: 1010px;
    overflow-y: auto;
}

.headerBox {
    height: 40px;
    line-height: 40px;
    font-size: 18px;
    font-weight: 600;
    color: #fff;
    width: 100%;
    position: absolute;
    top: 0;
    background-color: #999;
    display: flex;
}

.labBox {
    margin: 0 10px;
}

.CloseOutlined {
    position: absolute;
    right: 0;
    font-size: 20px;
    margin-top: 8px;
    margin-right: 8px;
}

.DataList {
    color: #fff;
    font-size: 16px;
    line-height: 35px;
}

.names {
    color: rgb(131, 248, 127);
    font-size: 16px;
}

.names_2 {
    font-size: 16px;
    white-space: pre;
}

.ciphertext {
    font-size: 14px !important;
}

.dataInput {
    color: #fff;
    border: none;
    outline: none !important;
    box-shadow: none;
    font-size: 16px;
    width: 70%;
    background: transparent;
    margin-left: -2px;
}

:deep().ant-input {
    color: #fff;
    background: transparent;
}
</style>